package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import network.Packet.packettype;

public class Receiver implements Runnable{

	byte[] m_buf;

	Packet[] m_receivedpackets;
	DatagramSocket m_socket;
	int m_queueIn, m_queueOut, m_queuedpackets,m_timestamp;
	boolean m_keeprunning;

	public Receiver(int portnum)
	{
		m_timestamp=0;
		m_queueIn=0;
		m_queueOut=0;
		m_queuedpackets=0;
		m_buf=new byte[1024];
		m_keeprunning=true;

		
		m_receivedpackets=new Packet[64];
		try {
			m_socket=new DatagramSocket(portnum);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override	
	public void run() {
		// TODO Auto-generated method stub
		while (m_keeprunning)
		{
			GetPacket();
		}
	}

	void GetPacket()
	{
		DatagramPacket packet=new DatagramPacket(m_buf,m_buf.length);
		
		try {
			m_socket.receive(packet);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			m_keeprunning=false;
			e.printStackTrace();
		}
		
		Decode(packet);
	}
	
	public void Discard()
	{
		m_socket.close();
	}

	  public void interrupt()
	 {
		 m_keeprunning=false;
		 //m_socket.close();
		 
	 }
	
	void Decode(DatagramPacket packet)
	{
		//convert byte buffer into a packet class
		//add it to the queue
		Packet p=Packet.Decode(packet);
		if (p.getType()==packettype.STATE)
		{
	
			if (p.getTimestamp()>m_timestamp)
			{
				m_timestamp=p.getTimestamp();
				m_queuedpackets++;
				m_receivedpackets[m_queueIn]=p;
				m_queueIn++; 
				if (m_queueIn>63)
				{
					m_queueIn=0;
				}						
			}		
		}
		else
		{
			m_queuedpackets++;
			m_receivedpackets[m_queueIn]=p;
			m_queueIn++; 
			if (m_queueIn>63)
			{
				m_queueIn=0;
			}
		}
	}
	
	public boolean PacketWaiting()
	{
		if (m_queuedpackets>0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public Packet TakePacket()
	{		
		Packet p=m_receivedpackets[m_queueOut];
		m_receivedpackets[m_queueOut]=null;
		m_queueOut++;
		if (m_queueOut>63)
		{
			m_queueOut=0;
		
		}
		if (p!=null)
		{
			m_queuedpackets--;
		}
		
		return p;
	}
	
	
}
